/*
 * @Author: jianglijun1004 
 * @Date: 2020-03-10 03:48:01 
 * @Last Modified by: jianglijun
 * @Last Modified time: 2020-03-13 00:07:54
 */
const xml2js = require('xml2js')
const crypto = require('crypto')
const {
  compiled
} = require('./tpl')
const parseXML = xml => {
  return new Promise((resolve, reject) => {
    xml2js.parseString(
      xml, {
        trim: true
      },
      (err, result) => {
        if (err) reject(err)
        else resolve(result)
      }
    )
  })
}
const formatMessage = message => {
  let result = {}
  if (typeof message === 'object') {
    const keys = Object.keys(message);
    for (let i = 0; i < keys.length; i++) {
      let item = message[keys[i]]
      let key = keys[i]
      if (!(item instanceof Array) || !(item.length)) {
        continue
      }
      if (item.length === 1) {
        let val = item[0]
        if (typeof val === 'object') {
          result[key] = formatMessage(val)
        } else {
          result[key] = (val || '').trim()
        }
      } else {
        result[key] = []
        for (let j = 0; j < item.length; j++) {
          result[key].push(formatMessage(item[j]))
        }
      }
    }
  }
  return result
}
const tpl = (content, message) => {
  const {
    FromUserName,
    ToUserName
  } = message
  let type = 'text';
  if (Array.isArray(content)) {
    type = 'news';
  }
  if (!content) conent = 'empty news';
  if (content && content.type) {
    type = content.type;
  }
  let info = Object.assign({}, {
    ToUserName: FromUserName,
    FromUserName: ToUserName,
    CreateTime: new Date().valueOf(),
    MsgType: type,
    Content: content
  })
  return compiled(info)
}
const timeout = async (ms) => {
  await new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};
// 随机字符串
const createNonce = () => {
  return Math.random().toString(36).substr(2, 16)
}
// 随机数
const createTimestame = () => {
  return parseInt(new Date().getTime() / 1000, 10) + ''
}

// 字典排序
const signIt = (paramsObj) => {
  let keys = Object.keys(paramsObj)
  let newArgs = {}
  let str = ''

  keys = keys.sort()
  keys.forEach(key => {
    newArgs[key.toLowerCase()] = paramsObj[key]
  })

  for (let k in newArgs) {
    str += '&' + k + '=' + newArgs[k]
  }

  return str.substr(1)
}
// 加密
const shaIt = (nonce, ticket, timestamp, url) => {
  const ret = {
    jsapi_ticket: ticket,
    nonceStr: nonce,
    timestamp: timestamp,
    url
  }

  const str = signIt(ret)
  let hash = crypto.createHash('sha1');
  hash.update(str);
  const sha = hash.digest('hex')
  return sha
}
// 加密签名的入口方法
const sign = (ticket, url) => {
  // 生成随机串
  const noncestr = createNonce()
  // 生成时间戳
  const timestamp = createTimestame()
  // 加密
  const signature = shaIt(noncestr, ticket, timestamp, url)
  return {
    noncestr,
    timestamp,
    signature
  }
}
exports = module.exports = {
  formatMessage,
  parseXML,
  timeout,
  tpl,
  sign
}
